Lịch sử C_(ngôn_ngữ_lập_trình)

Những phát triển ban đầu

Phát triển khởi đầu của C xảy ra ở AT&T Bell Labs giữa 19691973; theo Ritchie thì thời gian sáng tạo nhất là vào năm 1972. Nó được đặt tên là C vì nhiều đặc tính của nó rút ra từ một ngôn ngữ trước đó là B.

Thêm vào đó, các điểm khác với ngôn ngữ nguyên thủy "B": Ken Thompson kể tới ngôn ngữ lập trình BCPL, nhưng ông ta cũng đã tạo ra ngôn ngữ là Bon để vinh danh vợ mình.

Có nhiều truyền thuyết về nguồn gốc của C và hệ điều hành liên quan tới nó là Unix bao gồm:

  • Sự phát triển của C là kết quả của các lập trình viên đã muốn chơi Space Travel. Họ đã chơi nó trên mainframe của hãng làm việc, nhưng bị thiếu khả năng (chạy) và phải hỗ trợ khoảng 100 người dùng, Thompson và Ritchie tìm thấy rằng họ đã không có đủ sự kiểm soát tàu vũ trụ (của trò chơi) để tránh được các va chạm khỏi sự chuyển dịch của các thiên thạch. Do đó, họ quyết định để xuất trò chơi này sang một máy PDP-7 để không trong văn phòng. Nhưng nó lại không có hệ điều hành; do đó, họ viết một hệ điều hành. Tiếp tục, họ quyết định để xuất hệ điều hành này sang PDP-11 của văn phòng nhưng việc này thật khó vì tất cả mã đều là ngôn ngữ Assembly. Họ quyết định dùng một ngôn ngữ dễ xuất cấp cao để hệ điều hành có thể xuất được dễ dàng từ máy tính này sang máy khác. Họ đã tìm đến ngôn ngữ B, nhưng nó lại thiếu các chức năng để khai thác một số khả năng của PDP-11. Vậy nên họ đã sáng tạo ra một ngôn ngữ mới là C.
  • Unix nguyên đã được phát triển để tạo ra một hệ thống tự động lập hồ sơ cho các bằng phát minh. Phiên bản đầu tiên của Unix đã phát triển từ ngôn ngữ Assembly. Sau đó, ngôn ngữ C đã được phát triển để từ đó thay thế hệ điều hành mới.

Cho đến 1973, C đã trở nên đủ mạnh để dùng viết nhân cho Unix, thay vì trước nó chúng được viết bằng Assembly trong các máy PDP-11/20. Đây là lần đầu tiên mà nhân của một hệ điều hành được lắp thành bằng một ngôn ngữ khác hơn Assembly.

K&R C

Năm 1978, Ritchie và Brian Kernighan xuất bản lần đầu cuốn The C Programming Language. Sách này được những người lập trình biết tới như là "K&R", được dùng trong nhiều năm như là một đặc tả không chính thức của C. Phiên bản C mà cuốn sách đó đề cập thường được gọi là "K&R C". (Lần xuất bản thứ hai của cuốn này cũng bao gồm chuẩn ANSI C).

K&R giới thiệu các chức năng sau đây:

  • Kiểu dữ liệu struct
  • Kiểu dữ liệu long int
  • Kiểu dữ liệu unsigned int
  • Toán tử =+ đã được đổi thành +=, và tương tự cho các toán tử khác để tránh gây hiểu nhầm cho bộ phân tích từ vựng của trình dịch C. (Ví dụ: sự giống nhau dễ lầm lẫn của hai câu lệnh i =+ 10i = +10).

K&R C thường được xem là phần cơ bản nhất của ngôn ngữ mà nó cần phải có cho một trình dịch C. Trong nhiều năm, ngay cả sau khi ANSI C được giới thiệu, nó đã được xem như là "mẫu số chung nhỏ nhất" mà người lập trình C phải bám lấy nếu muốn có được khả năng dịch chuyển (tái dụng trên nhiều máy) bởi vì không phải mọi trình dịch đều hỗ trợ toàn bộ ANSI C, và một cách hợp lý là mã viết trong K&R C cũng là mã hợp lệ trong ANSI C.

Trong các phiên bản trước đây của C, chỉ có những hàm nào trả về một số khác số nguyên mới cần được khai báo trước khi dùng. Một hàm dùng mà không có bất kì sự khai báo nào trước đó được giả thiết là sẽ trả về một số nguyên.

Ví dụ việc gọi với yêu cầu của sự khai báo trước:

1  long int SomeFunction();2  3  int CallingFunction()4  {5      long int ret;6      ret = SomeFunction();7  }

Ví dụ việc gọi mà không cần phải khai báo trước:

 1  int CallingFunction() 2  { 3      int ret; 4      ret = SomeOtherFunction(); 5  } 6   7  int SomeOtherFunction() 8  { 9      return 0;10  }

Bởi vì nguyên mẫu của K&R đã không bao gồm bất kì thông tin nào về các tham số của hàm, chức năng kiểm tra kiểu của các đối số đã không được tiến hành, mặc dù một số trình dịch sẽ cho ra thông báo cảnh cáo nếu một hàm đã được gọi với số lượng tham số không đúng.

Trong nhiều năm tiếp theo của sự tái bản K&R C, nhiều chức năng "không chính thức" đã được thêm vào cho ngôn ngữ, được hỗ trợ bởi các trình dịch của AT&T và một số nơi khác. Trong đó bao gồm:

  • Các hàm có kiểu void và dữ liệu có kiểu void *.
  • Các hàm trả về các kiểu struct hay union.
  • Tên của các miền trong một không gian tên cho mỗi kiểu struct.
  • Phép gán cho kiểu dữ liệu struct.
  • Hằng const được xem là đối tượng chỉ cho phép đọc.
  • Một thư viện chuẩn được sự hợp tác để xây dựng bởi nhiều nhà sản xuất.
  • Các kiểu enumeration.
  • Kiểu chính xác đơn float.

ANSI C và ISO C

Vào khoảng cuối thập niên 1970, C bắt đầu thay thế vai trò của BASIC như là một ngôn ngữ lập trình cho microcomputer. Suốt thập niên 1980 nó đã được chấp thuận dùng trong IBM PC, và sự phổ biến của nó bắt đầu tăng một cách lớn lao.

Trong cùng thời kỳ, Bjarne Stroustrup và đồng nghiệp ở Bell Labs đã bắt tay cho thêm vào C các cấu trúc ngôn ngữ lập trình hướng đối tượng.

Ngôn ngữ họ tạo ra gọi là C++ nay trở thành ngôn ngữ lập trình ứng dụng phổ biến nhất trên hệ điều hành Microsoft Windows; C vẫn còn rất phổ biến trong thế giới UNIX. Một ngôn ngữ khác cũng được phát triển trong khoảng thời gian này là Objective-C, cũng là một mở rộng lập trình hướng đối tượng cho C. Dù không phổ biến như C++, nó được dùng để phát triển các ứng dụng Cocoa của Mac OS X.

Trong 1983, Viện Tiêu chuẩn Quốc gia Hoa Kỳ (ANSI) thành lập hội đồng X3J11 để hoàn tất một tiêu chuẩn dặc tả của C. Sau một quá trình khó khăn và lâu dài, tiêu chuẩn đã hoàn tất vào 1989 và được công nhận là "Programming Language C" ANSI X3.159-1989. Phiên bản ngôn ngữ này thường được nhắc đến như là ANSI C.

Trong 1990, Tiêu chuẩn ANSI C (với một vài chi tiết nhỏ được điều chỉnh) đã được tiêu chuẩn hóa bởi Tổ chức Quốc tế về Tiêu chuẩn hóa (ISO) như là ISO/IEC 9899:1990.

Một điểm mạnh của quá trình tiêu chuẩn hoá ANSI C là làm cho K&R C trở thành một tập con của nó; nó tiếp nhận nhiều chức năng không chính thức của K&R C như là một hệ quả. Xa hơn, hội đồng tiêu chuẩn cũng làm cho ANSI C bao gồm thêm nhiều chức năng mới, như là các nguyên mẫu của hàm (mượn từ C++), và khả năng tiền xử lý mạnh hơn.

Ngày nay, ANSI C được hỗ trợ bởi hầu hết các trình dịch. Hầu hết các mã C ngày nay được viết dựa ttrên ANSI C. Mọi chương trình chỉ viết trong chuẩn C thì sẽ đảm bảo việc thực thi chính xác trên mọi nền nào cho phép dùng C. Mặc dù vậy, nhiều chương trình đã viết ra chỉ dịch được trong một số nền hoặc với một số trình dịch nào đó bởi vì các lý do sau:

  1. Dùng các thư viện không chuẩn, như là cho GUI.
  2. Một số trình dịch không hoàn toàn theo đúng chuẩn ANSI C hay các chuẩn tiếp sau trong các chế độ làm việc mặc nhiên của chúng.
  3. Phụ thuộc vào kích thước của một số kiểu dữ liệu cũng như là endian của nền. (Chẳng hạn, trong một số nền kích thước của kiểu int có thể nhiều hơn hay ít hơn—4, 8 hay 16 byte—trong nền khác.)

Macro __STDC__ có thể được dùng để chẻ mã nguồn thành các phần theo ANSI C và K&R

1 #if __STDC__2 extern int getopt(int,char * const *,const char *);3 #else4 extern int getopt();5 #endif

Một số chuyên gia khuyên rằng dùng #if __STDC__ như trên, thay cho #ifdef __STDC__ bởi vì một số trình dịch cài giá trị __STDC__ về 0 để chỉ việc không theo chuẩn ANSI (trong khi một số trình dịch khác lại cài về giá trị khác 0).

C99

Sau quá trình chuẩn hóa ANSI, đặc tả của ngôn ngữ C tương đối được giữ nguyên trong một thời gian, trong khi C++ tiếp tục thâm nhập. (Đúng ra, đã có tu chính số 1 tạo ra phiên bản mới của C trong 1995, nhưng phiên bản này hiếm khi được đồng thuận.) Cho đến cuối thập niên 1990 một tiêu chuẩn mới đã được phát hành là ISO 9899:1999. Tiêu chuẩn này thường được mệnh danh là "C99". Nó đã tiếp thu ANSI C trong tháng 3 năm 2000.

Những chức năng mới trong C99 bao gồm:

  • Các hàm inline.
  • Các biến có thể được khai báo ở bất kì chỗ nào (như là trong C++).
  • Nhiều kiểu dữ liệu mới được đưa vào bao gồm kiểu long long int (để giảm khó khăn trong việc chuyển hệ từ 32-bit sang 64-bit), kiểu boolean và kiểu complex để dùng cho các số phức.
  • Các mảng có chiều dài thay đổi được.
  • Hỗ trợ cho dòng lệnh chú giải bắt đầu với // như trong C++ và nhiều ngôn ngữ khác.
  • Nhiều hàm thư viện mới như là snprintf().
  • Nhiều tập tin tiêu dề như là stdint.h.

Điều thú vị trong việc hỗ trợ cho chuẩn C99 là một kết quả pha trộn. Trong khi GCC và nhiều trình dịch khác hiện hỗ trợ hầu hết các chức năng của C99, thì trình dịch của MicrosoftBorland lại không tuân theo và hai công ty này dường như không thích thú để thêm vào các hỗ trợ này.

Tài liệu tham khảo

WikiPedia: C_(ngôn_ngữ_lập_trình) http://www.csse.monash.edu.au/~damian/papers/HTML/... http://www.research.att.com/~bs/bs_faq.html#really... http://www.research.att.com/~bs/sibling_rivalry.pd... http://cm.bell-labs.com/cm/cs/who/dmr/chist.html http://cm.bell-labs.com/cm/cs/who/dmr/spacetravel.... http://www-106.ibm.com/developerworks/linux/librar... http://homepage.ntlworld.com/dmjones/cbook1_0a.pdf http://david.tribble.com/text/cdiffs.htm http://www.library.cornell.edu/nr/bookcpdf/c1-2.pd... http://catalogue.bnf.fr/ark:/12148/cb119665180